package com.gitee.wsl.time.chinese

import com.gitee.wsl.text.format.format
import com.gitee.wsl.time.chinese.bean.NineStar
import com.gitee.wsl.time.chinese.util.LunarUtil
import com.gitee.wsl.time.chinese.util.LunarUtil.getTimeJi
import com.gitee.wsl.time.chinese.util.LunarUtil.getTimeYi
import com.gitee.wsl.time.chinese.util.LunarUtil.getTimeZhiIndex
import com.gitee.wsl.time.chinese.util.LunarUtil.getXun
import com.gitee.wsl.time.chinese.util.LunarUtil.getXunKong


/**
 * 时辰
 *
 * @author 6tail
 */
class LunarTime(lunarYear: Int, lunarMonth: Int, lunarDay: Int, hour: Int, minute: Int, second: Int) {
    /**
     * 天干下标，0-9
     */
    val ganIndex: Int

    /**
     * 地支下标，0-11
     */
    val zhiIndex: Int

    /**
     * 阴历
     */
    private val lunar: Lunar

    init {
        this.lunar = Lunar.fromYmdHms(lunarYear, lunarMonth, lunarDay, hour, minute, second)
        this.zhiIndex = getTimeZhiIndex(String.format("%02d:%02d", hour, minute))
        this.ganIndex = (lunar.dayGanIndexExact % 5 * 2 + zhiIndex) % 10
    }

    val shengXiao: String
        /**
         * 获取生肖
         *
         * @return 生肖，如虎
         */
        get() = LunarUtil.SHENGXIAO[zhiIndex + 1]

    val zhi: String
        /**
         * 获取地支
         *
         * @return 地支
         */
        get() = LunarUtil.ZHI[zhiIndex + 1]

    val gan: String
        /**
         * 获取天干
         *
         * @return 天干
         */
        get() = LunarUtil.GAN[ganIndex + 1]

    val ganZhi: String
        /**
         * 获取干支（时柱）
         *
         * @return 干支（时柱）
         */
        get() = this.gan + this.zhi

    val positionXi: String
        /**
         * 获取喜神方位
         *
         * @return 喜神方位，如艮
         */
        get() = LunarUtil.POSITION_XI[ganIndex + 1]

    val positionXiDesc: String
        /**
         * 获取喜神方位描述
         *
         * @return 喜神方位描述，如东北
         */
        get() = LunarUtil.POSITION_DESC.get(this.positionXi)!!

    val positionYangGui: String
        /**
         * 获取阳贵神方位
         *
         * @return 阳贵神方位，如艮
         */
        get() = LunarUtil.POSITION_YANG_GUI[ganIndex + 1]

    val positionYangGuiDesc: String
        /**
         * 获取阳贵神方位描述
         *
         * @return 阳贵神方位描述，如东北
         */
        get() = LunarUtil.POSITION_DESC.get(this.positionYangGui)!!

    val positionYinGui: String
        /**
         * 获取阴贵神方位
         *
         * @return 阴贵神方位，如艮
         */
        get() = LunarUtil.POSITION_YIN_GUI[ganIndex + 1]

    val positionYinGuiDesc: String
        /**
         * 获取阴贵神方位描述
         *
         * @return 阴贵神方位描述，如东北
         */
        get() = LunarUtil.POSITION_DESC.get(this.positionYinGui)!!

    val positionFu: String
        /**
         * 获取福神方位（默认流派：2）
         *
         * @return 福神方位，如艮
         */
        get() = getPositionFu(2)

    /**
     * 获取福神方位
     *
     * @param sect 流派，1或2
     * @return 福神方位，如艮
     */
    fun getPositionFu(sect: Int): String {
        return (if (1 == sect) LunarUtil.POSITION_FU else LunarUtil.POSITION_FU_2)[ganIndex + 1]
    }

    val positionFuDesc: String
        /**
         * 获取福神方位描述（默认流派：2）
         *
         * @return 福神方位描述，如东北
         */
        get() = getPositionFuDesc(2)

    /**
     * 获取福神方位描述
     *
     * @param sect 流派，1或2
     * @return 福神方位描述，如东北
     */
    fun getPositionFuDesc(sect: Int): String {
        return LunarUtil.POSITION_DESC.get(getPositionFu(sect))!!
    }

    val positionCai: String
        /**
         * 获取财神方位
         *
         * @return 财神方位，如艮
         */
        get() = LunarUtil.POSITION_CAI[ganIndex + 1]

    val positionCaiDesc: String
        /**
         * 获取财神方位描述
         *
         * @return 财神方位描述，如东北
         */
        get() = LunarUtil.POSITION_DESC.get(this.positionCai)!!

    val naYin: String
        /**
         * 获取纳音
         *
         * @return 纳音，如剑锋金
         */
        get() = LunarUtil.NAYIN.get(this.ganZhi)!!

    val tianShen: String
        /**
         * 获取值时天神
         *
         * @return 值时天神
         */
        get() = LunarUtil.TIAN_SHEN[(zhiIndex + LunarUtil.ZHI_TIAN_SHEN_OFFSET.get(lunar.dayZhiExact)!!) % 12 + 1]

    val tianShenType: String
        /**
         * 获取值时天神类型：黄道/黑道
         *
         * @return 值时天神类型：黄道/黑道
         */
        get() = LunarUtil.TIAN_SHEN_TYPE.get(this.tianShen)!!

    val tianShenLuck: String
        /**
         * 获取值时天神吉凶
         *
         * @return 吉/凶
         */
        get() = LunarUtil.TIAN_SHEN_TYPE_LUCK.get(this.tianShenType)!!

    val chong: String
        /**
         * 获取时冲
         *
         * @return 时冲，如申
         */
        get() = LunarUtil.CHONG[zhiIndex]

    val sha: String
        /**
         * 获取时煞
         *
         * @return 时煞，如北
         */
        get() = LunarUtil.SHA.get(this.zhi)!!

    val chongShengXiao: String
        /**
         * 获取时冲生肖
         *
         * @return 时冲生肖，如猴
         */
        get() {
            val chong = this.chong
            var i = 0
            val j = LunarUtil.ZHI.size
            while (i < j) {
                if (LunarUtil.ZHI[i].equals(chong)) {
                    return LunarUtil.SHENGXIAO[i]
                }
                i++
            }
            return ""
        }

    val chongDesc: String
        /**
         * 获取时冲描述
         *
         * @return 时冲描述，如(壬申)猴
         */
        get() = "(" + this.chongGan + this.chong + ")" + this.chongShengXiao

    val chongGan: String
        /**
         * 获取无情之克的时冲天干
         *
         * @return 无情之克的时冲天干，如甲
         */
        get() = LunarUtil.CHONG_GAN[ganIndex]

    val chongGanTie: String
        /**
         * 获取有情之克的时冲天干
         *
         * @return 有情之克的时冲天干，如甲
         */
        get() = LunarUtil.CHONG_GAN_TIE[ganIndex]

    val yi: List<String?>?
        /**
         * 获取宜，如果没有，返回["无"]
         *
         * @return 宜
         */
        get() = getTimeYi(lunar.dayInGanZhiExact, this.ganZhi)

    val ji: List<String?>?
        /**
         * 获取忌，如果没有，返回["无"]
         *
         * @return 忌
         */
        get() = getTimeJi(lunar.dayInGanZhiExact, this.ganZhi)

    val nineStar: NineStar
        /**
         * 获取值时九星（时家紫白星歌诀：三元时白最为佳，冬至阳生顺莫差，孟日七宫仲一白，季日四绿发萌芽，每把时辰起甲子，本时星耀照光华，时星移入中宫去，顺飞八方逐细查。夏至阴生逆回首，孟归三碧季加六，仲在九宫时起甲，依然掌中逆轮跨。）
         *
         * @return 值时九星
         */
        get() {
            //顺逆
            val solarYmd = lunar.solar.toYmd()
            val jieQi = lunar.jieQiTable
            val asc = solarYmd.compareTo(jieQi.get("冬至")!!.toYmd()) >= 0 && solarYmd.compareTo(
                jieQi.get("夏至")!!.toYmd()
            ) < 0
            var start = if (asc) 7 else 3
            val dayZhi = lunar.dayZhi
            if ("子午卯酉".contains(dayZhi)) {
                start = if (asc) 1 else 9
            } else if ("辰戌丑未".contains(dayZhi)) {
                start = if (asc) 4 else 6
            }
            var index = if (asc) start + zhiIndex - 1 else start - zhiIndex - 1
            if (index > 8) {
                index -= 9
            }
            if (index < 0) {
                index += 9
            }
            return NineStar(index)
        }

    val xun: String
        /**
         * 获取所在旬
         *
         * @return 旬
         */
        get() = getXun(this.ganZhi)

    val xunKong: String
        /**
         * 获取值时空亡
         *
         * @return 空亡(旬空)
         */
        get() = getXunKong(this.ganZhi)

    val minHm: String
        /**
         * 获取当前时辰的最早时分
         *
         * @return 时分，如：21:00
         */
        get() {
            val hour = lunar.hour
            if (hour < 1) {
                return "00:00"
            } else if (hour > 22) {
                return "23:00"
            }
            return String.format("%02d:00", if (hour % 2 == 0) hour - 1 else hour)
        }

    val maxHm: String
        /**
         * 获取当前时辰的最晚时分
         *
         * @return 时分，如：22:59
         */
        get() {
            val hour = lunar.hour
            if (hour < 1) {
                return "00:59"
            } else if (hour > 22) {
                return "23:59"
            }
            return String.format("%02d:59", if (hour % 2 == 0) hour else hour + 1)
        }

    override fun toString(): String {
        return this.ganZhi
    }

    companion object {
        fun fromYmdHms(lunarYear: Int, lunarMonth: Int, lunarDay: Int, hour: Int, minute: Int, second: Int): LunarTime {
            return LunarTime(lunarYear, lunarMonth, lunarDay, hour, minute, second)
        }
    }
}
